<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>URL 音乐播放器</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <style>
        :root {
            --primary-color: #2196f3;
            --secondary-color: #ffffff;
            --text-color: #333333;
            --progress-bg: #e0e0e0;
            --hover-color: rgba(33, 150, 243, 0.1);
            --active-color: #1976D2;
            --error-color: #f44336;
            --success-color: #4CAF50;
        }

        body {
            margin: 0;
            padding: 0;
            font-family: 'Arial', sans-serif;
            background: linear-gradient(135deg, #1e88e5, #0d47a1);
            color: var(--text-color);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .player-container {
            width: 90%;
            max-width: 500px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
            backdrop-filter: blur(10px);
        }

        .player-header {
            text-align: center;
            margin-bottom: 30px;
        }

        .player-title {
            font-size: 2em;
            color: var(--primary-color);
            margin: 0;
            font-weight: bold;
        }

        .player-subtitle {
            color: #666;
            margin-top: 5px;
            font-size: 0.9em;
        }

        .input-group {
            margin: 25px 0;
            position: relative;
        }

        .input-group label {
            display: block;
            margin-bottom: 10px;
            color: var(--text-color);
            font-weight: bold;
            font-size: 0.9em;
            text-transform: uppercase;
            letter-spacing: 1px;
        }

        .input-group input {
            width: 100%;
            padding: 15px;
            border: 2px solid var(--progress-bg);
            border-radius: 12px;
            font-size: 14px;
            transition: all 0.3s ease;
            outline: none;
            background: rgba(255, 255, 255, 0.9);
        }

        .input-group input:focus {
            border-color: var(--primary-color);
            box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);
        }

        .control-panel {
            background: var(--hover-color);
            border-radius: 15px;
            padding: 20px;
            margin: 20px 0;
        }

        .button-group {
            display: flex;
            gap: 10px;
            justify-content: center;
        }

        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 12px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
            min-width: 120px;
        }

        .btn i {
            font-size: 16px;
        }

        .btn-primary {
            background: var(--primary-color);
            color: white;
        }

        .btn-primary:hover {
            background: var(--active-color);
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(33, 150, 243, 0.3);
        }

        .btn-danger {
            background: var(--error-color);
            color: white;
        }

        .btn-danger:hover {
            background: #d32f2f;
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(244, 67, 54, 0.3);
        }

        .playback-control {
            margin-top: 30px;
            padding: 20px;
            border-radius: 15px;
            background: var(--hover-color);
            display: none;
            animation: slideDown 0.3s ease;
        }

        @keyframes slideDown {
            from { 
                opacity: 0;
                transform: translateY(-20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .playback-control.active {
            display: block;
        }

        .progress-container {
            margin: 15px 0;
        }

        .progress-bar {
            width: 100%;
            height: 6px;
            background: var(--progress-bg);
            border-radius: 3px;
            cursor: pointer;
            position: relative;
            overflow: hidden;
        }

        .progress-current {
            height: 100%;
            background: var(--primary-color);
            border-radius: 3px;
            width: 0%;
            transition: width 0.1s linear;
            position: relative;
        }

        .progress-current::after {
            content: '';
            position: absolute;
            right: -2px;
            top: 50%;
            transform: translateY(-50%);
            width: 12px;
            height: 12px;
            background: white;
            border: 2px solid var(--primary-color);
            border-radius: 50%;
            display: none;
        }

        .progress-bar:hover .progress-current::after {
            display: block;
        }

        .time-display {
            display: flex;
            justify-content: space-between;
            font-size: 12px;
            color: var(--text-color);
            margin-top: 8px;
            font-weight: bold;
        }

        .volume-control {
            margin-top: 30px;
            padding: 20px;
            border-radius: 15px;
            background: var(--hover-color);
        }

        .volume-control label {
            display: flex;
            align-items: center;
            gap: 8px;
            color: var(--text-color);
            font-weight: bold;
            margin-bottom: 10px;
        }

        .volume-slider {
            width: 100%;
            height: 4px;
            -webkit-appearance: none;
            background: var(--progress-bg);
            border-radius: 2px;
            outline: none;
            margin: 10px 0;
        }

        .volume-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 16px;
            height: 16px;
            background: var(--primary-color);
            border: 2px solid white;
            border-radius: 50%;
            cursor: pointer;
            transition: all 0.2s ease;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
        }

        .volume-slider::-webkit-slider-thumb:hover {
            transform: scale(1.2);
            box-shadow: 0 2px 8px rgba(33, 150, 243, 0.4);
        }

        .volume-value {
            text-align: center;
            color: var(--text-color);
            font-size: 0.9em;
            margin-top: 5px;
        }

        .status {
            margin-top: 20px;
            padding: 15px;
            border-radius: 12px;
            text-align: center;
            display: none;
            animation: fadeIn 0.3s ease;
            font-weight: bold;
        }

        .status.success {
            background: #e8f5e9;
            color: var(--success-color);
        }

        .status.error {
            background: #ffebee;
            color: var(--error-color);
        }

        .status.loading {
            background: #e3f2fd;
            color: var(--primary-color);
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .wave-animation {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 3px;
            height: 20px;
            margin-top: 10px;
        }

        .wave-bar {
            width: 3px;
            height: 100%;
            background: var(--primary-color);
            border-radius: 3px;
            animation: wave 1s ease-in-out infinite;
        }

        @keyframes wave {
            0%, 100% { transform: scaleY(0.3); }
            50% { transform: scaleY(1); }
        }

        .wave-bar:nth-child(2) { animation-delay: 0.1s; }
        .wave-bar:nth-child(3) { animation-delay: 0.2s; }
        .wave-bar:nth-child(4) { animation-delay: 0.3s; }
        .wave-bar:nth-child(5) { animation-delay: 0.4s; }
    </style>
</head>
<body>
    <div class="player-container">
        <div class="player-header">
            <h1 class="player-title">URL 音乐播放器</h1>
            <p class="player-subtitle">支持在线音频流播放</p>
        </div>

        <div class="input-group">
            <label for="urlInput">音频地址</label>
            <input type="text" id="urlInput" placeholder="请输入音频流URL地址">
        </div>

        <div class="control-panel">
            <div class="button-group">
                <button class="btn btn-primary" onclick="streamPlayer.playStream()">
                    <i class="fas fa-play"></i> 播放
                </button>
                <button class="btn btn-danger" onclick="streamPlayer.stopStream()">
                    <i class="fas fa-stop"></i> 停止
                </button>
            </div>
        </div>

        <div id="playbackControl" class="playback-control">
            <div class="wave-animation">
                <div class="wave-bar"></div>
                <div class="wave-bar"></div>
                <div class="wave-bar"></div>
                <div class="wave-bar"></div>
                <div class="wave-bar"></div>
            </div>
            <div class="progress-container">
                <div class="progress-bar" id="progressBar">
                    <div class="progress-current" id="progressCurrent"></div>
                </div>
                <div class="time-display">
                    <span id="currentTime">00:00</span>
                    <span id="totalTime">00:00</span>
                </div>
            </div>
            <div class="button-group">
                <button class="btn btn-primary" onclick="streamPlayer.togglePause()">
                    <i class="fas fa-pause" id="pauseIcon"></i>
                    <span id="pauseText">暂停</span>
                </button>
            </div>
        </div>

        <div class="volume-control">
            <label for="volumeSlider">
                <i class="fas fa-volume-up"></i> 音量控制
            </label>
            <input type="range" id="volumeSlider" class="volume-slider" min="0" max="63" step="1">
            <div class="volume-value" id="volumeValue">当前音量: 32</div>
        </div>

        <div id="status" class="status"></div>
    </div>

    <script>
        const streamPlayer = {
            isPlaying: false,
            isPaused: false,
            currentPosition: 0,
            totalDuration: 0,
            progressInterval: null,
            startTime: null,
            currentUrl: null,

            formatTime: function(seconds) {
                const mins = Math.floor(seconds / 60);
                const secs = Math.floor(seconds % 60);
                return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
            },

            updateProgress: function() {
                if (!this.isPlaying || this.isPaused) return;
                
                const now = Date.now();
                const elapsed = (now - this.startTime) / 1000;
                const currentTime = this.currentPosition + elapsed;
                
                document.getElementById('currentTime').textContent = this.formatTime(currentTime);
                
                if (this.totalDuration > 0) {
                    const progress = (currentTime / this.totalDuration) * 100;
                    document.getElementById('progressCurrent').style.width = `${Math.min(progress, 100)}%`;
                }
            },

            startProgressTracking: function() {
                this.progressInterval = setInterval(() => this.updateProgress(), 100);
            },

            stopProgressTracking: function() {
                if (this.progressInterval) {
                    clearInterval(this.progressInterval);
                    this.progressInterval = null;
                }
            },

            playStream: async function() {
                const url = document.getElementById('urlInput').value;
                if (!url) {
                    showStatus('请输入有效的 URL', true);
                    return;
                }

                try {
                    if (this.isPlaying) {
                        await this.stopStream();
                    }

                    showStatus('正在加载音频...', false, true);
                    const response = await fetch('/api/music/stream', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ url }),
                    });

                    const data = await response.json();
                    if (!response.ok) {
                        throw new Error(data.error || '播放失败');
                    }

                    if (!data.duration) {
                        throw new Error('无法获取时长信息');
                    }

                    const duration = data.duration;
                    this.totalDuration = duration.TotalSeconds;
                    document.getElementById('totalTime').textContent = 
                        `${String(duration.Minutes).padStart(2, '0')}:${String(duration.Seconds).padStart(2, '0')}`;

                    this.isPlaying = true;
                    this.isPaused = false;
                    this.startTime = Date.now();
                    this.currentUrl = url;
                    this.currentPosition = 0;
                    this.startProgressTracking();
                    
                    document.getElementById('playbackControl').classList.add('active');
                    document.querySelector('#pauseIcon').className = 'fas fa-pause';
                    document.querySelector('#pauseText').textContent = '暂停';
                    showStatus('正在播放');
                } catch (error) {
                    showStatus(error.message, true);
                }
            },

            stopStream: async function() {
                try {
                    const response = await fetch('/api/music/stop', {
                        method: 'POST'
                    });

                    if (!response.ok) {
                        throw new Error('停止播放失败');
                    }

                    this.isPlaying = false;
                    this.isPaused = false;
                    this.currentPosition = 0;
                    this.currentUrl = null;
                    this.stopProgressTracking();
                    document.getElementById('playbackControl').classList.remove('active');
                    document.getElementById('progressCurrent').style.width = '0%';
                    document.getElementById('currentTime').textContent = '00:00';
                    showStatus('已停止播放');
                } catch (error) {
                    showStatus('停止播放失败: ' + error.message, true);
                }
            },

            togglePause: async function() {
                if (!this.isPlaying) return;

                try {
                    const endpoint = this.isPaused ? '/api/music/resume' : '/api/music/pause';
                    const response = await fetch(endpoint, {
                        method: 'POST'
                    });

                    if (!response.ok) {
                        throw new Error(this.isPaused ? '继续播放失败' : '暂停播放失败');
                    }

                    this.isPaused = !this.isPaused;
                    if (this.isPaused) {
                        const elapsed = (Date.now() - this.startTime) / 1000;
                        this.currentPosition += elapsed;
                        this.stopProgressTracking();
                        document.querySelector('#pauseIcon').className = 'fas fa-play';
                        document.querySelector('#pauseText').textContent = '继续';
                    } else {
                        this.startTime = Date.now();
                        this.startProgressTracking();
                        document.querySelector('#pauseIcon').className = 'fas fa-pause';
                        document.querySelector('#pauseText').textContent = '暂停';
                    }
                } catch (error) {
                    showStatus(error.message, true);
                }
            },

            seekTo: async function(position) {
                if (!this.isPlaying) return;
                
                try {
                    const response = await fetch('/api/music/seek', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ position }),
                    });

                    if (!response.ok) {
                        throw new Error('跳转失败');
                    }

                    this.currentPosition = position;
                    this.startTime = Date.now();
                    
                    if (this.isPaused) {
                        this.isPaused = false;
                        this.startProgressTracking();
                        document.querySelector('#pauseIcon').className = 'fas fa-pause';
                        document.querySelector('#pauseText').textContent = '暂停';
                    }
                } catch (error) {
                    showStatus('跳转失败: ' + error.message, true);
                }
            }
        };

        function showStatus(message, isError = false, loading = false) {
            const status = document.getElementById('status');
            status.textContent = message + (loading ? '...' : '');
            status.style.display = 'block';
            status.className = 'status' + (isError ? ' error' : loading ? ' loading' : ' success');
            
            if (!loading) {
                setTimeout(() => {
                    status.style.display = 'none';
                }, 3000);
            }
        }

        // 音量控制
        const volumeControl = {
            init: async function() {
                try {
                    const response = await fetch('/api/volume/get');
                    if (!response.ok) {
                        throw new Error('获取音量失败');
                    }
                    const data = await response.json();
                    const volume = parseInt(data.volume);
                    
                    const slider = document.getElementById('volumeSlider');
                    const volumeValue = document.getElementById('volumeValue');
                    
                    slider.value = volume;
                    volumeValue.textContent = `当前音量: ${volume}`;
                } catch (error) {
                    console.error('初始化音量失败:', error);
                }
            },

            setVolume: async function(volume) {
                try {
                    const response = await fetch('/api/volume/set', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ volume: volume.toString() }),
                    });

                    if (!response.ok) {
                        throw new Error('设置音量失败');
                    }

                    document.getElementById('volumeValue').textContent = `当前音量: ${volume}`;
                } catch (error) {
                    console.error('设置音量失败:', error);
                }
            }
        };

        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            volumeControl.init();

            const slider = document.getElementById('volumeSlider');
            let timeoutId = null;

            slider.addEventListener('input', function() {
                document.getElementById('volumeValue').textContent = `当前音量: ${this.value}`;
            });

            slider.addEventListener('change', function() {
                if (timeoutId) {
                    clearTimeout(timeoutId);
                }
                
                timeoutId = setTimeout(() => {
                    volumeControl.setVolume(this.value);
                }, 100);
            });

            // 从 localStorage 恢复上次的输入
            const lastUrl = localStorage.getItem('lastStreamUrl');
            if (lastUrl) {
                document.getElementById('urlInput').value = lastUrl;
            }

            // 保存输入到 localStorage
            document.getElementById('urlInput').addEventListener('change', function() {
                localStorage.setItem('lastStreamUrl', this.value);
            });

            // 进度条点击跳转
            const progressBar = document.getElementById('progressBar');
            progressBar.addEventListener('click', function(e) {
                if (!streamPlayer.isPlaying) return;
                
                const rect = this.getBoundingClientRect();
                const position = (e.clientX - rect.left) / rect.width;
                const newPosition = position * streamPlayer.totalDuration;
                streamPlayer.seekTo(newPosition);
            });
        });
    </script>
</body>
</html> 